home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / book / src / menu.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  40KB  |  1,322 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <stdarg.h>
  4. #include    <string.h>
  5. #include    <ctype.h>
  6. #include    <egb.h>
  7. #include    <mos.h>
  8. #include    "event.h"
  9. #include    "init.h"
  10. #include    "book.h"
  11. #include    "cons.h"
  12. #include    "keyio.h"
  13. #include    "menu.h"
  14. #include    "lib.h"
  15. #include    "mouse.h"
  16.  
  17. #define SC  STD_COL
  18. #define B1  BOX1_COL
  19. #define B2  BOX2_COL
  20. #define WC  WIND_COL
  21. #define BC  BTN_COL
  22.  
  23. #define MEVT_l  128     /*  地の画面の最低メニューレベル  */
  24. #define MEVT    131     /*  ここで使う最高メニューレベル  */
  25.  
  26. #define Ymin    32      /*  画面の最大位置  */
  27. #define Ymax1   470     /*  画面の最大位置  */
  28. #define Ymax2   450     /*  画面の最大位置  */
  29. #define Xmin    3       /*  画面の最大位置  */
  30. #define Xmax    642     /*  画面の最大位置  */
  31.  
  32. #define MAX_SW  16
  33.  
  34. #define LINE_STYLE  (0xFF00FF00)
  35. #undef  LINE_STYLE
  36. #define LINE_STYLE  (0xFFFFFFFF)
  37.  
  38.  
  39. /* ***  メッセージ・ボックスの定義  *** */
  40.  
  41. typedef struct  {
  42.     char    *str ;              /*  ボタンの文字列  */
  43.     short   x ;                 /*  ボタンの位置  */
  44.     short   evt ;               /*  イベント番号  */
  45. }   btn_prm ;
  46. typedef struct  {
  47.     char    *str ;              /*  スイッチの文字列  */
  48.     short   x, y ;              /*  スイッチの位置  */
  49.     short   sw ;                /*  スイッチの状態  */
  50.     short   evt ;               /*  イベント番号  */
  51. }   sw_prm ;
  52.  
  53. typedef struct      /*  メニューを移動したときの位置情報を渡すための構造体  */
  54. {
  55.     short   xpos, ypos;             /*  開始位置  */
  56.     short   xsiz, ysiz;             /*  大きさ  */
  57.     mevt_t  evt;                    /*  移動時に発生するイベント  */
  58.  
  59.     short   ymax;                   /*  Y方向の画面の最大範囲  */
  60.  
  61.     char    *ttl;                   /*  タイトル文字列へのポインタ  */
  62.     short   ttly;                   /*  タイトル開始位置  */
  63.     short   ttllen;                 /*  タイトル文字数  */
  64.  
  65.     btn_prm btn[MAX_BTN_MSG];       /*  ボタンの文字列  */
  66.     short   btny;                   /*  ボタンの位置  */
  67.     short   btnlen;                 /*  ボタンの文字数  */
  68.     short   btnnum;                 /*  ボタンの数  */
  69.     short   btnxsiz, btnysiz;       /*  ボタンの大きさ  */
  70.  
  71.     sw_prm  sw[MAX_SW] ;            /*  スイッチ文字列・位置・大きさ  */
  72.     short   swxsiz, swysiz ;        /*  スイッチの大きさ  */
  73.     short   swnum ;                 /*  スイッチの数  */
  74.  
  75.     char    *msg[MAX_DSP_MSG] ;     /*  メッセージ文字列  */
  76.     short   msgx, msgy ;            /*  メッセージ文字列開始位置  */
  77.     short   msgpitch ;              /*  メッセージ表示行ピッチ  */
  78.     short   msgnum, msglen ;        /*  メッセージ文字列の数と最大文字数  */
  79.  
  80.     void    (*func)(int) ;          /*  画面再描画ルーチンへのポインタ  */
  81. } MENU_PRM ;
  82.  
  83. static  MENU_PRM    menu = {0, 0};
  84. static  mevt_t      menu_event = MEv_NULL;
  85. static  int         curpos = -1;
  86.  
  87.  
  88. int     move_menu( int last_x,int last_y, int nx,int ny, int xs,int ys )
  89. {
  90.     struct {
  91.         short   x1,y1, x2,y2;
  92.     }   para;
  93.     short   mx = nx - last_x;
  94.     short   my = ny - last_y;
  95.  
  96.     if (last_x > nx) iswap(&nx, &last_x);
  97.     if (last_y > ny) iswap(&ny, &last_y);
  98.     para.x1 = last_x, para.y1 = last_y;
  99.     para.x2 = nx+xs,  para.y2 = ny+ys;
  100.  
  101.     MOS_disp(MOS_OFF);
  102.     EGB_color(gwork, 1, 0);
  103.     EGB_partScroll(gwork, 1, mx,my, (char *)¶);
  104.     MOS_disp(MOS_ON);
  105.  
  106.     return TRUE;
  107. }
  108.  
  109. int     X(x)
  110. {
  111.     return ( x % 2 ) ? x : x+1 ;
  112. }
  113.  
  114. #if 1
  115. static  void    ROLL_clip( REGS evt_t *ep, int x, int y, int sw )
  116. {
  117. static  int     s_lx = 0,s_ly = 0, s_mofs_x = 0,s_mofs_y = 0 ;
  118.         int     lx,ly, mofs_x,mofs_y;
  119.  
  120.     lx = s_lx;
  121.     ly = s_ly;
  122.     mofs_x = s_mofs_x;
  123.     mofs_y = s_mofs_y;
  124.  
  125.     sw = sw;
  126.  
  127.     switch(ep->now)
  128.     {
  129.       case Ev_CLIP_MOS:
  130.         mos_ptn(MOSCSR_HAND);
  131.         menu_event = ep->no;
  132.         ep->now = Ev_REP_MOS;
  133.         ep->x1 = x-menu.xpos+Xmin;
  134.         ep->x2 = Xmax-((menu.xpos+menu.xsiz)-x);
  135.         ep->y1 = y-menu.ypos+Ymin;
  136.         ep->y2 = menu.ymax-((menu.ypos+menu.ysiz)-y);
  137.         MOS_horizon (ep->x1, ep->x2);
  138.         MOS_vertical(ep->y1, ep->y2);
  139.         mofs_x = x - menu.xpos, mofs_y = y - menu.ypos;
  140.         lx = X(x - mofs_x), ly = y - mofs_y;
  141.         MOS_disp(MOS_OFF);
  142.         box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1, 15,LINE_STYLE,MODE_XOR);
  143. #ifdef MOS_CSR_DISPLAY
  144.         MOS_disp(MOS_ON);
  145. #endif
  146.         break;
  147.  
  148.       case Ev_REP_MOS:
  149.         if (lx != X(x - mofs_x) || ly != y - mofs_y)
  150.         {
  151. int llx,lly;
  152. #ifdef MOS_CSR_DISPLAY
  153.             MOS_disp(MOS_OFF);
  154. #endif
  155.             llx = lx, lly= ly;
  156.             lx = X(x - mofs_x), ly = y - mofs_y;
  157.  
  158.             box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1,
  159.                                                     15,LINE_STYLE,MODE_XOR);
  160.             box(llx+1,lly+1, llx+menu.xsiz-1,lly+menu.ysiz-1,
  161.                                                     15,LINE_STYLE,MODE_XOR);
  162. #ifdef MOS_CSR_DISPLAY
  163.             MOS_disp(MOS_ON);
  164. #endif
  165.         }
  166.         break;
  167.  
  168.       case Ev_DOLACK_MOS:
  169.         ep->now = Ev_NON;
  170.       case Ev_MOVE_MOS:
  171.       case Ev_OFF_MOS:
  172.         mos_ptn(MOSCSR_FINGER);
  173.         break;
  174.  
  175.       case Ev_SELECT_MOS:
  176. #ifdef MOS_CSR_DISPLAY
  177.         MOS_disp(MOS_OFF);
  178. #endif
  179.         mos_dispoff(ON);
  180.         box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1, 15,LINE_STYLE,MODE_XOR);
  181.         ep->x1 = menu.xpos, ep->x2 = menu.xpos + menu.xsiz;
  182.         ep->y1 = menu.ypos, ep->y2 = menu.ypos + menu.ysiz;
  183.         menu_event = ep->no;
  184.         if (lx != menu.xpos || ly != menu.ypos)
  185.         {
  186.             move_menu(menu.xpos,menu.ypos, lx,ly, menu.xsiz,menu.ysiz);
  187.             menu.xpos = lx; menu.ypos = ly;
  188.             menu.func(NO);
  189.         }
  190.         MOS_horizon (MIN_HORIZON,  max_horizon);
  191.         MOS_vertical(MIN_VERTICAL, MAX_VERTICAL);
  192.  
  193.         mos_dispoff(OFF);
  194.         ep->now = Ev_ON_MOS;
  195.       case Ev_ON_MOS:
  196.         mos_ptn(MOSCSR_HAND);
  197.         MOS_disp(MOS_ON);
  198.         break;
  199.     }
  200.  
  201.     s_lx = lx;
  202.     s_ly = ly;
  203.     s_mofs_x = mofs_x;
  204.     s_mofs_y = mofs_y;
  205. }
  206. #else
  207. static  void    ROLL_clip( REGS evt_t *ep, int x, int y, int sw )
  208. {
  209. static  int     lx = 0,ly = 0, mofs_x = 0,mofs_y = 0 ;
  210.  
  211.     sw = sw;
  212.  
  213.     switch(ep->now)
  214.     {
  215.       case Ev_CLIP_MOS:
  216.         mos_ptn(MOSCSR_HAND);
  217.         menu_event = ep->no;
  218.         ep->now = Ev_REP_MOS;
  219.         ep->x1 = x-menu.xpos+Xmin;
  220.         ep->x2 = Xmax-((menu.xpos+menu.xsiz)-x);
  221.         ep->y1 = y-menu.ypos+Ymin;
  222.         ep->y2 = menu.ymax-((menu.ypos+menu.ysiz)-y);
  223.         MOS_horizon (ep->x1, ep->x2);
  224.         MOS_vertical(ep->y1, ep->y2);
  225.         mofs_x = x - menu.xpos, mofs_y = y - menu.ypos;
  226.         lx = X(x - mofs_x), ly = y - mofs_y;
  227.         MOS_disp(MOS_OFF);
  228.         box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1, 15,LINE_STYLE,MODE_XOR);
  229. #ifdef MOS_CSR_DISPLAY
  230.         MOS_disp(MOS_ON);
  231. #endif
  232.         break;
  233.  
  234.       case Ev_REP_MOS:
  235.         if (lx != X(x - mofs_x) || ly != y - mofs_y)
  236.         {
  237. #ifdef MOS_CSR_DISPLAY
  238.             MOS_disp(MOS_OFF);
  239. #endif
  240.             box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1,
  241.                                                     15,LINE_STYLE,MODE_XOR);
  242.             lx = X(x - mofs_x), ly = y - mofs_y;
  243.             box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1,
  244.                                                     15,LINE_STYLE,MODE_XOR);
  245. #ifdef MOS_CSR_DISPLAY
  246.             MOS_disp(MOS_ON);
  247. #endif
  248.         }
  249.         break;
  250.  
  251.       case Ev_DOLACK_MOS:
  252.         ep->now = Ev_NON;
  253.       case Ev_MOVE_MOS:
  254.       case Ev_OFF_MOS:
  255.         mos_ptn(MOSCSR_FINGER);
  256.         break;
  257.  
  258.       case Ev_SELECT_MOS:
  259. #ifdef MOS_CSR_DISPLAY
  260.         MOS_disp(MOS_OFF);
  261. #endif
  262.         mos_dispoff(ON);
  263.         box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1, 15,LINE_STYLE,MODE_XOR);
  264.         ep->x1 = menu.xpos, ep->x2 = menu.xpos + menu.xsiz;
  265.         ep->y1 = menu.ypos, ep->y2 = menu.ypos + menu.ysiz;
  266.         menu_event = ep->no;
  267.         if (lx != menu.xpos || ly != menu.ypos)
  268.         {
  269.             move_menu(menu.xpos,menu.ypos, lx,ly, menu.xsiz,menu.ysiz);
  270.             menu.xpos = lx; menu.ypos = ly;
  271.             menu.func(NO);
  272.         }
  273.         MOS_horizon (MIN_HORIZON,  max_horizon);
  274.         MOS_vertical(MIN_VERTICAL, MAX_VERTICAL);
  275.  
  276.         mos_dispoff(OFF);
  277.         ep->now = Ev_ON_MOS;
  278.       case Ev_ON_MOS:
  279.         mos_ptn(MOSCSR_HAND);
  280.         MOS_disp(MOS_ON);
  281.         break;
  282.     }
  283. }
  284. #endif
  285.  
  286. void    DSP_clip_paint(evt_t *ep)
  287. {
  288.     MOS_disp(MOS_OFF);
  289.  
  290.     EGB_writeMode(gwork, MODE_XOR);
  291.     pbox(ep->x1+1,ep->y1+1, ep->x2-1,ep->y2-1, 2,2);
  292.     EGB_writeMode(gwork, MODE_PSET);
  293.  
  294.     MOS_disp(MOS_ON);
  295. }
  296.  
  297. static  void    MENU_clip( REGS evt_t *ep, int x, int y, int sw )
  298. {
  299. int     now ;
  300.  
  301.     y = y, sw = sw ;    /*  意味なし。ワーニングを避けるため  */
  302.  
  303.     now = ep->now ;
  304.  
  305.     switch( now )
  306.     {
  307.       case Ev_CLIP_MOS:
  308.         mos_ptn( MOSCSR_HAND ) ;
  309.         if( isrepeat( ep ) )
  310.             ep->now = Ev_REP_MOS ;
  311.         if( !isclip( ep ) )
  312.         {
  313.             if( ispaint( ep ) )
  314.                 DSP_clip_paint( ep ) ;
  315.             else
  316.                 DSP_clip_on( ep ) ;
  317.         }
  318.         break ;
  319.  
  320.       case Ev_REP_MOS:     /*  リピート動作は特になし  */
  321.         break ;
  322.  
  323.       case Ev_DOLACK_MOS:
  324.         ep->now = Ev_NON ;
  325.       case Ev_MOVE_MOS:
  326.         if( !isclip( ep ) )
  327.         {
  328.             if( ispaint( ep ) )
  329.                 DSP_clip_paint( ep ) ;
  330.             else
  331.                 DSP_clip_off( ep ) ;
  332.         }
  333.       case Ev_OFF_MOS:
  334.         mos_ptn( MOSCSR_FINGER ) ;
  335.         break ;
  336.  
  337.       case Ev_SELECT_MOS:
  338.         menu_event = ep->no ;
  339.         if( iscsr( ep ) )
  340.             curpos = (x-ep->x1) / 8 ;
  341.         if( !isclip( ep ) )
  342.         {
  343.             if( ispaint( ep ) )
  344.                 DSP_clip_paint( ep ) ;
  345.             else
  346.                 DSP_clip_off( ep ) ;
  347.         }
  348.         ep->now = Ev_ON_MOS ;
  349.       case Ev_ON_MOS:
  350.         mos_ptn( MOSCSR_HAND ) ;
  351.         break ;
  352.     }
  353. }
  354.  
  355. static  void    RIGHT_click( void )
  356. {
  357.     menu_event = MEv_CANCEL ;
  358. }
  359.  
  360. static  void    DSP_select_mode( int redraw )
  361. {
  362.     auto    int     i ;
  363.     auto    int     ttlx,ttly, ttlxsiz,ttlysiz ;
  364.     auto    int     xpos,ypos, btnx,btny ;
  365.  
  366.     xpos = menu.xpos ;
  367.     ypos = menu.ypos ;
  368.  
  369.     /*  設定  */
  370.     mos_ptn( MOSCSR_FINGER ) ;
  371.  
  372.     /*  タイトルの位置と大きさ決め  */
  373.     ttlxsiz = menu.ttllen * 8 + 8 ;
  374.     ttlysiz = 22 ;
  375.     ttlx = xpos + (menu.xsiz - ttlxsiz) / 2 ;
  376.     ttly = ypos + menu.ttly ;
  377.  
  378.     /*  ボタンの位置と大きさ決め  */
  379.     btny = ypos + menu.btny ;
  380.  
  381.     /*  画面作成とイベント登録  */
  382.     EVT_level_free( MEVT ) ;
  383.     EVT_level_free( MEVT-1 ) ;
  384.  
  385.     /*  メニューウィンドゥの表示  */
  386.     if( redraw )
  387.     {
  388.         pbox( xpos,  ypos,   xpos+menu.xsiz,  ypos+menu.ysiz, BAK_COL,BAK_COL);
  389.         pbox( xpos+1,ypos+1, xpos+menu.xsiz-1,ypos+menu.ysiz-1, WC,WC ) ;
  390.         box2( xpos+3,ypos+3, xpos+menu.xsiz-3,ypos+menu.ysiz-3, B1,B2 ) ;
  391.     }
  392.     EVT_set_node( xpos,ypos, menu.xsiz,menu.ysiz,
  393.                                             MEVT-1,ROLL_clip,menu.evt, LOCK ) ;
  394.  
  395.     /*  タイトル表示  */
  396.     if( redraw )
  397.     {
  398.         box2( ttlx,ttly, ttlx+ttlxsiz,ttly+ttlysiz, B1,B2 ) ;
  399.         wrt( menu.ttl,
  400.                 ttlx+4+(menu.ttllen-strlen(menu.ttl))*4,ttly+3, SC,WC, 16 ) ;
  401.     }
  402.  
  403.     /*  メッセージ表示  */
  404.     if( redraw )
  405.     {
  406.         for( i = 0 ; i < menu.msgnum ; i ++ )
  407.         {
  408.             ttlx = (menu.msglen - strlen(menu.msg[i])) * 4;
  409.             wrt( menu.msg[i],
  410.                         xpos+ttlx+4,ypos+16+24+i*menu.msgpitch, SC,WC, 16 ) ;
  411.         }
  412.     }
  413.  
  414.     /*  ボタンの表示とイベント登録  */
  415.     for( i = 0 ; i < menu.btnnum ; i ++ )
  416.     {
  417.         btnx = xpos + menu.btn[i].x ;
  418.         if( redraw )
  419.         {
  420.             dsp_box( btnx,btny, btnx+menu.btnxsiz,btny+menu.btnysiz, B1,B2,BC);
  421.             wrt( center(menu.btn[i].str, menu.btnlen), btnx+4,btny+3,SC,BC,16);
  422.         }
  423.         EVT_set_node( btnx,btny, menu.btnxsiz,menu.btnysiz,
  424.                                     MEVT,MENU_clip,menu.btn[i].evt, NOP ) ;
  425.     }
  426.     EVT_set_cancel( MEVT, RIGHT_click ) ;
  427. }
  428.  
  429. /*  ボタン・メッセージなどの数と大きさを数える  */
  430. /*  戻り値 : str[] に btn[] をコピー、*len に最大文字列長
  431.     関数の返り値 : 個数  */
  432. static  int     count_prm( char *btn[], int max, short *len )
  433. {
  434.     int     i ;
  435.  
  436.     for( *len = i = 0 ; i < max ; i++ )
  437.     {
  438.         if( btn[i] == NULL )
  439.             break ;
  440.  
  441.         if( strlen( btn[i] ) > *len )
  442.             *len = strlen( btn[i] ) ;
  443.     }
  444.     return i ;
  445. }
  446.  
  447. int     select_mode(char *ttl, char *msg[], char *btn[],
  448.                                     int pitch, int *xcenter, int *ycenter)
  449. {
  450. static  int     menu_x = 160, menu_y = 210;
  451.         int     i, ch;
  452.  
  453.     if (xcenter != NULL)
  454.         menu_x = *xcenter;
  455.     if (ycenter != NULL)
  456.         menu_y = *ycenter;
  457.  
  458.     menu.func = DSP_select_mode ;
  459.     menu.ymax = Ymax1 ;
  460.  
  461.     pbox(Xmin,Ymin, Xmax,Ymax1, 0,0);   /*  clear screen  */
  462.  
  463.     /*  ボタンの数と大きさ  */
  464.     menu.btnnum = count_prm(btn, MAX_BTN_MSG, &menu.btnlen);
  465.     for( i = 0 ; i < menu.btnnum ; i ++ )
  466.         menu.btn[i].str = btn[i], menu.btn[i].evt = MEv_MAX + i;
  467.     if( menu.btnlen < 8 )   menu.btnlen = 8 ;
  468.     else                    menu.btnlen += menu.btnlen % 2 ;
  469.     menu.btnxsiz = menu.btnlen * 8 + 8 ;
  470.     menu.btnysiz = 22 ;
  471.  
  472.     /*  メッセージの行数と大きさ  */
  473.     menu.msgnum = count_prm( msg, MAX_DSP_MSG, &menu.msglen ) ;
  474.     for (i = 0; i < menu.msgnum; i++)
  475.         menu.msg[i] = msg[i];
  476.     if (menu.msglen < 30)   menu.msglen = 34;
  477.     else                    menu.msglen += (menu.msglen % 2) + 4;
  478.     menu.msgpitch = pitch;
  479.  
  480.     /*  スイッチの数  */
  481.     menu.swnum = 0;
  482.  
  483.     /*  ウィンドゥの大きさと位置  */
  484.     menu.xsiz = menu.msglen * 8 + 8 ;
  485.     menu.ysiz = menu.msgnum * pitch + 20 + 24 + 24 ;
  486.     if (menu_x == MENU_CENTERING) {    /*  X centering  */
  487.         menu_x = ((Xmax - Xmin) - menu.xsiz) / 2;
  488.     }
  489.     if (menu_y == MENU_CENTERING) {    /*  Y centering  */
  490.         menu_y = ((Ymax1 - Ymin) - menu.ysiz) / 2;
  491.     }
  492.     if (X((menu.xpos = menu_x) + menu.xsiz) > X(Xmax))
  493.         menu.xpos = X(Xmax - menu.xsiz) ;
  494.     if (menu.xpos < Xmin)
  495.         menu.xpos = Xmin;
  496.     if ((menu.ypos = menu_y) + menu.ysiz > menu.ymax)
  497.         menu.ypos = menu.ymax - menu.ysiz;
  498.     if (menu.ypos < Ymin)
  499.         menu.ypos = Ymin;
  500.     menu.evt = MEv_NULL;
  501.  
  502.     if( menu.msgnum < 1 || menu.btnnum > MAX_BTN_MSG )
  503.         return( FALSE ) ;
  504.  
  505.     /*  タイトルの大きさと位置  */
  506.     menu.ttl = ttl ;
  507.     menu.ttllen = ( strlen( ttl ) > 16 ) ? strlen( ttl ) : 16 ;
  508.     menu.ttly = 6 ;
  509.  
  510.     /*  ボタンの位置  */
  511.     menu.btny = menu.ysiz - 28 ;
  512.     switch (menu.btnnum)
  513.     {
  514.       case 1:
  515.         menu.btn[0].x = ( menu.xsiz - menu.btnxsiz ) /2 ;
  516.         break ;
  517.  
  518.       case 2:
  519.         menu.btn[0].x = menu.xsiz/2 - menu.btnxsiz - 4 ;
  520.         menu.btn[1].x = menu.xsiz/2 + 4 ;
  521.         break ;
  522.  
  523.       case 3:
  524.         menu.btn[1].x = ( menu.xsiz - menu.btnxsiz ) / 2 ;
  525.         menu.btn[0].x = menu.btn[1].x - menu.btnxsiz - 8 ;
  526.         menu.btn[2].x = menu.btn[1].x + menu.btnxsiz + 8 ;
  527.         break ;
  528.     }
  529.  
  530.  
  531.     /*  画面作成  */
  532.     MOS_disp(MOS_OFF);
  533.  
  534.     DSP_select_mode(YES);
  535.  
  536.     /*  ループの開始  */
  537.     MOS_disp(MOS_ON);
  538.  
  539.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  540.  
  541.     do {
  542.         menu_event = MEv_NULL;
  543.         while (menu_event == MEv_NULL && (ch = kb_check()) == 0)
  544.             EVT_loop(MEVT_l, MEVT);
  545.  
  546.         if (ch != 0)
  547.         {
  548.             switch (ch)
  549.             {
  550.               case 0x01:        /*  エスケープで中止  */
  551.                 menu_event = MEv_CANCEL;    break;
  552.               case 0x73: case 0x1D: case 0x45: /*  改行、実行キーで決定  */
  553.                 menu_event = MEv_MAX;
  554.             }
  555.         }
  556.     } while (menu_event == MEv_NULL);
  557.  
  558.     MOS_disp(MOS_OFF);
  559.  
  560.     EVT_level_free(MEVT);
  561.  
  562.     pbox(menu.xpos,menu.ypos, menu.xpos+menu.xsiz,menu.ypos+menu.ysiz, 0,0);
  563.  
  564.     MOS_disp(MOS_ON);
  565.  
  566.     menu_x = menu.xpos;
  567.     menu_y = menu.ypos;
  568.     if (xcenter != NULL)
  569.         *xcenter = menu_x;
  570.     if (ycenter != NULL)
  571.         *ycenter = menu_y;
  572.  
  573.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  574.  
  575.     return menu_event == MEv_CANCEL ? -1:(menu_event - MEv_MAX + 1);
  576. }
  577.  
  578. int     select_drive(void)
  579. {
  580. static  int     menu_x = 160, menu_y = 210;
  581.         int     ch, drv = -1;
  582. const   int     pitch = 24;
  583.  
  584.     menu.func = DSP_select_mode;
  585.     menu.ymax = Ymax1;
  586.  
  587.     pbox(Xmin,Ymin, Xmax,Ymax1, 0,0);   /*  clear screen  */
  588.  
  589.     /*  ボタンの数と大きさ  */
  590.     menu.btnnum = 1;
  591.     menu.btn[0].str = "中  止";
  592.     menu.btn[0].evt = MEv_MAX;
  593.     menu.btnlen = 8;
  594.     menu.btnxsiz = menu.btnlen * 8 + 8;
  595.     menu.btnysiz = 22;
  596.  
  597.     /*  メッセージの行数と大きさ  */
  598.     menu.msgnum = 2;
  599.     menu.msg[0] = "ドライブ名を入力してください (A-Q)";
  600.     menu.msg[1] = "ドライブ名 : _";
  601.     menu.msglen = strlen(menu.msg[0]) + 4;
  602.     menu.msgpitch = pitch;
  603.  
  604.     /*  スイッチの数  */
  605.     menu.swnum = 0;
  606.  
  607.     /*  ウィンドゥの大きさと位置  */
  608.     menu.xsiz = menu.msglen * 8 + 8;
  609.     menu.ysiz = menu.msgnum * pitch + 20 + 24 + 24;
  610.     if (X((menu.xpos = menu_x) + menu.xsiz) > X(Xmax))
  611.         menu.xpos = X(Xmax - menu.xsiz) ;
  612.     if (menu.xpos < Xmin)
  613.         menu.xpos = Xmin;
  614.     if ((menu.ypos = menu_y) + menu.ysiz > menu.ymax)
  615.         menu.ypos = menu.ymax - menu.ysiz;
  616.     if (menu.ypos < Ymin)
  617.         menu.ypos = Ymin;
  618.     menu.evt = MEv_NULL;
  619.  
  620.     /*  タイトルの大きさと位置  */
  621.     menu.ttl = "ドライブ選択";
  622.     menu.ttllen = 16;
  623.     menu.ttly = 6;
  624.  
  625.     /*  ボタンの位置  */
  626.     menu.btny = menu.ysiz - 28;
  627.     menu.btn[0].x = (menu.xsiz - menu.btnxsiz) / 2;
  628.  
  629.  
  630.     /*  画面作成  */
  631.     MOS_disp(MOS_OFF);
  632.  
  633.     DSP_select_mode(YES);
  634.  
  635.     /*  ループの開始  */
  636.     MOS_disp(MOS_ON);
  637.  
  638.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  639.  
  640.     do {
  641.         menu_event = MEv_NULL;
  642.         while (menu_event == MEv_NULL && (ch = kb_check()) == 0)
  643.             EVT_loop(MEVT_l, MEVT);
  644.  
  645.         if (ch != 0)
  646.         {
  647.             if (ch == 0x01)     /* エスケープで中止 */
  648.                 menu_event = MEv_CANCEL;
  649.             else                /* その他のキー入力 */
  650.             {
  651.                 ch = sc_to_char[ch];
  652.                 if (ch >= 'A' && ch <= 'Z') /* ドライブ名 */
  653.                     drv = ch - 'A';
  654.             }
  655.         }
  656.     } while (menu_event == MEv_NULL && drv < 0);
  657.  
  658.     MOS_disp(MOS_OFF);
  659.  
  660.     EVT_level_free(MEVT);
  661.  
  662.     pbox(menu.xpos,menu.ypos, menu.xpos+menu.xsiz,menu.ypos+menu.ysiz, 0,0);
  663.  
  664.     MOS_disp(MOS_ON);
  665.  
  666.     menu_x = menu.xpos;
  667.     menu_y = menu.ypos;
  668.  
  669.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  670.  
  671.     return menu_event == MEv_CANCEL ? -1:drv;
  672. }
  673.  
  674.  
  675. static  int     DSP_rev( int s1, int s2 )
  676. {
  677.     void    disp( char *str, int x,int y, int fc,int bc )
  678.     {
  679.         x += menu.xpos, y += menu.ypos ;
  680.         dsp_box( x,y, x+menu.swxsiz,y+menu.swysiz, B1,B2, bc ) ;
  681.         wrt( str, x+4,y+2, fc,bc, 16 ) ;
  682.     }
  683.  
  684.     MOS_disp( MOS_OFF ) ;
  685.     disp( menu.sw[s1].str, menu.sw[s1].x,menu.sw[s1].y, SC,WC ) ;
  686.     disp( menu.sw[s2].str, menu.sw[s2].x,menu.sw[s2].y, BLACK_l,WHITE_l ) ;
  687.     MOS_disp( MOS_ON ) ;
  688.  
  689.     return s2 ;
  690. }
  691.  
  692. static  void    DSP_switch( int redraw )
  693. {
  694.     short   i, x,y, col,bak ;
  695.  
  696.     for( i = 0 ; i < menu.swnum ; i ++ )
  697.     {
  698.         if( redraw )
  699.         {
  700.             if( menu.sw[i].sw == TRUE ) col = BLACK_l, bak = WHITE_l ;
  701.             else                        col = SC,      bak = WIND_COL ;
  702.             x = menu.xpos+menu.sw[i].x, y = menu.ypos+menu.sw[i].y ;
  703.             dsp_box( x,y, x+menu.swxsiz,y+menu.swysiz, B1,B2,bak ) ;
  704.             wrt( menu.sw[i].str, x+4,y+2, col,bak, 16 ) ;
  705.         }
  706.         EVT_set_node( menu.xpos+menu.sw[i].x, menu.ypos+menu.sw[i].y,
  707.             menu.swxsiz,menu.swysiz, MEVT,MENU_clip,menu.sw[i].evt, NOP ) ;
  708.     }
  709. }
  710.  
  711. static  void    DSP_select_form( int redraw )
  712. {
  713.     DSP_select_mode(redraw);
  714.  
  715.     /*  スイッチ表示  */
  716.     if (redraw)
  717.     {
  718.         wrt("改行表示(V)", menu.xpos+16,menu.ypos+42,      SC,WC,16);
  719.         wrt("制御文字(C)", menu.xpos+16,menu.ypos+42+28,   SC,WC,16);
  720.         wrt("タブ展開(T)", menu.xpos+16,menu.ypos+42+28*2, SC,WC,16);
  721.         wrt("行 間 隔(L)", menu.xpos+16,menu.ypos+42+28*4, SC,WC,16);
  722.     }
  723.  
  724.     /*  スイッチ表示  */
  725.     DSP_switch(redraw);
  726. }
  727.  
  728. mevt_t  select_form(int *disp_cr, int *tab_siz, int *dpl_mode, int *form_ctrl)
  729. {
  730. static  int     menu_x = 150, menu_y = 60;
  731.         int     i, ch, cr = 0, tab = 0, dot = 0, ctrl = 0;
  732. #define BX1 120
  733. #define BX2 200
  734. #define BX3 280
  735.  
  736.     cr = *disp_cr ? 0 : 1 ;
  737.     dot = *dpl_mode ;
  738.     ctrl = *form_ctrl ;
  739.     switch( *tab_siz )
  740.     {
  741.       case 0:   tab = 0 ;   break ;
  742.       case 1:   tab = 1 ;   break ;
  743.       case 4:   tab = 2 ;   break ;
  744.       case 8:   tab = 3 ;   break ;
  745.     }
  746.  
  747.     menu.func = DSP_select_form;
  748.     menu.ymax = Ymax1;
  749.  
  750.     /*  ウィンドゥの大きさと位置  */
  751.     menu.xsiz = 372, menu.ysiz = 216;
  752.     if (X((menu.xpos = menu_x) + menu.xsiz) > X(Xmax))
  753.         menu.xpos = X(Xmax - menu.xsiz);
  754.     if ((menu.ypos = menu_y) + menu.ysiz > menu.ymax)
  755.         menu.ypos = menu.ymax - menu.ysiz;
  756.     menu.evt = MEv_NULL;
  757.  
  758.     /*  タイトル  */
  759.     menu.ttl = "書式設定";
  760.     menu.ttllen = strlen(menu.ttl) + 4;
  761.     menu.ttly = 6;
  762.  
  763.     /*  スイッチの指定  */
  764.     menu.swnum = 11;
  765.     menu.sw[0].str = " す  る ", menu.sw[0].x = BX1;
  766.     menu.sw[1].str = " しない ", menu.sw[1].x = BX2;
  767.                                         menu.sw[0].y = menu.sw[1].y = 40;
  768.     menu.sw[2].str = "そのまま", menu.sw[2].x = BX1;
  769.     menu.sw[3].str = "整形表示", menu.sw[3].x = BX2;
  770.                                         menu.sw[2].y = menu.sw[3].y = 40+28;
  771.     menu.sw[4].str = " しない ", menu.sw[4].x = BX1, menu.sw[4].y = 40+28*2;
  772.     menu.sw[5].str = "1カラム", menu.sw[5].x = BX1;
  773.     menu.sw[6].str = "4カラム", menu.sw[6].x = BX2;
  774.     menu.sw[7].str = "8カラム", menu.sw[7].x = BX3;
  775.                     menu.sw[5].y = menu.sw[6].y = menu.sw[7].y = 40+28*3;
  776.     menu.sw[8].str = "16ドット", menu.sw[8].x = BX1;
  777.     menu.sw[9].str = "18ドット", menu.sw[9].x = BX2;
  778.     menu.sw[10].str= "20ドット", menu.sw[10].x= BX3;
  779.                     menu.sw[8].y = menu.sw[9].y = menu.sw[10].y = 40+28*4;
  780.     menu.swxsiz = 72, menu.swysiz = 19;
  781.     for (i = 0; i < menu.swnum; i++)
  782.         menu.sw[i].sw = OFF, menu.sw[i].evt = MEv_MAX + i;
  783.     menu.sw[0+cr].sw = menu.sw[2+ctrl].sw =
  784.     menu.sw[4+tab].sw = menu.sw[8+dot].sw = ON;
  785.  
  786.     /*  ボタンの登録  */
  787.     menu.btnnum = 1;
  788.     menu.btn[0].evt = MEv_SELECT;
  789.     menu.btn[0].str = " 決 定 ";
  790.     menu.btnlen = strlen(menu.btn[0].str);
  791.     menu.btnxsiz = menu.btnlen * 8 + 8;
  792.     menu.btnysiz = 22;
  793.     menu.btn[0].x = menu.xsiz/2 - menu.btnxsiz/2;
  794.     menu.btny = menu.ysiz - 28;
  795.  
  796.     /*  メッセージはなし  */
  797.     menu.msgnum = 0 ;
  798.  
  799.     /*  画面作成  */
  800.     MOS_disp(MOS_OFF);
  801.  
  802.     DSP_select_form(YES);
  803.  
  804.     /*  ループの開始  */
  805.     MOS_disp(MOS_ON);
  806.  
  807.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  808.  
  809.     do {
  810.         menu_event = MEv_NULL;
  811.         while ((ch = kb_check()) == 0 && menu_event == MEv_NULL)
  812.             EVT_loop(MEVT_l, MEVT);
  813.  
  814.         if (ch)
  815.         {
  816.             switch (ch)
  817.             {
  818.               case 0x01: case 0x11:         /*  エスケープ、'Q' で中止  */
  819.                 menu_event = MEv_CANCEL;    break;
  820.               case 0x73: case 0x1D: case 0x45: /*  改行、実行キーで決定  */
  821.                 menu_event = MEv_SELECT;
  822.                 break;
  823.               case 0x2D:        /* V で改行選択 */
  824.                 if ((menu_event = cr + 1) > 1)
  825.                     menu_event = 0;
  826.                 menu_event += MEv_MAX;
  827.                 break;
  828.               case 0x2C:        /* C で制御文字選択 */
  829.                 if ((menu_event = ctrl + 1) > 1)
  830.                     menu_event = 0;
  831.                 menu_event += MEv_MAX + 2;
  832.                 break;
  833.               case 0x15:        /* T でタブ選択 */
  834.                 if ((menu_event = tab + 1) > 3)
  835.                     menu_event = 0;
  836.                 menu_event += MEv_MAX + 4;
  837.                 break;
  838.               case 0x26:        /* L で行間隔選択 */
  839.                 if ((menu_event = dot + 1) > 2)
  840.                     menu_event = 0;
  841.                 menu_event += MEv_MAX + 8;
  842.                 break;
  843.               case 0x0B: case 0x46:     /* 0 */
  844.                 menu_event += MEv_MAX + 4; break;
  845.               case 0x02: case 0x43:     /* 1 */
  846.                 menu_event += MEv_MAX + 5; break;
  847.               case 0x05: case 0x3E:     /* 4 */
  848.                 menu_event += MEv_MAX + 6; break;
  849.               case 0x09: case 0x3B:     /* 8 */
  850.                 menu_event += MEv_MAX + 7; break;
  851.             }
  852.         }
  853.  
  854.         switch (menu_event)
  855.         {
  856.           case MEv_MAX:  case MEv_MAX+1:
  857.             if (cr != (menu_event - MEv_MAX))
  858.                 cr = DSP_rev(cr, menu_event - MEv_MAX) - 0;
  859.             break;
  860.  
  861.           case MEv_MAX+2:  case MEv_MAX+3:
  862.             if (ctrl != (menu_event - (MEv_MAX+2)))
  863.                 ctrl = DSP_rev(ctrl+2, menu_event - MEv_MAX) - 2;
  864.             break;
  865.  
  866.           case (MEv_MAX+4):  case (MEv_MAX+5):
  867.           case (MEv_MAX+6):  case (MEv_MAX+7):
  868.             if (tab != (menu_event - (MEv_MAX+4)))
  869.                 tab = DSP_rev(tab+4, menu_event - MEv_MAX) - 4;
  870.             break ;
  871.  
  872.           case (MEv_MAX+8):  case (MEv_MAX+9):  case (MEv_MAX+10):
  873.             if (dot != (menu_event - (MEv_MAX+8)))
  874.                 dot = DSP_rev(dot+8, menu_event - MEv_MAX) - 8;
  875.             break;
  876.         }
  877.         while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  878.     } while (menu_event != MEv_SELECT && menu_event != MEv_CANCEL);
  879.  
  880.     MOS_disp(MOS_OFF);
  881.  
  882.     /*  結果  */
  883.     if (menu_event != MEv_CANCEL)
  884.     {
  885.         *disp_cr = cr == 0 ? TRUE : FALSE ;
  886.         *dpl_mode = dot ;
  887.         *form_ctrl = ctrl ;
  888.         switch (tab)
  889.         {
  890.           case 0:   *tab_siz = 0;   break;
  891.           case 1:   *tab_siz = 1;   break;
  892.           case 2:   *tab_siz = 4;   break;
  893.           case 3:   *tab_siz = 8;   break;
  894.         }
  895.     }
  896.  
  897.     EVT_level_free(MEVT);
  898.  
  899.     pbox(menu.xpos,menu.ypos, menu.xpos+menu.xsiz,menu.ypos+menu.ysiz, 0,0);
  900.  
  901.     MOS_disp(MOS_ON);
  902.  
  903.     menu_x = menu.xpos;
  904.     menu_y = menu.ypos;
  905.  
  906.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  907.  
  908.     return menu_event;
  909. }
  910.  
  911. int     check_exit(void)
  912. {
  913. static  int     xc = MENU_CENTERING, yc = MENU_CENTERING;
  914.  
  915.     msg[0] = "終了しますか?" ;
  916.     msg[1] = NULL ;
  917.     btn[0] = "終  了" ;
  918.     btn[1] = "取  消" ;
  919.     btn[2] = NULL ;
  920.     return select_mode("確  認", msg, btn, 28, &xc,&yc);
  921. }
  922.  
  923. int     select_drag(evt_t *homebtn, int ttlsave,
  924.                      int x,int y, int xsiz, char *msg[], char *keytbl)
  925. {
  926. int     i, ofs, btn_num;
  927. int     cancel, ground, ch;
  928. int     pos = -1;
  929. char    *p;
  930. evt_t   *ev[EXCMD_MAX], *ep = NULL;
  931.  
  932.  
  933.     if (ttlsave)
  934.         title_backup(ON);   /* タイトル部分の退避 */
  935.  
  936.     MOS_disp(MOS_OFF);
  937.  
  938.     /*  画面作成とイベント登録  */
  939.     EVT_level_free(MEVT);
  940.     EVT_level_free(MEVT-1);
  941.  
  942.     EVT_set_ground(MEVT-1, RIGHT_click, LEFT);
  943.     ground = EVT_control_ground(ON);
  944.     EVT_set_cancel(MEVT-1, RIGHT_click);
  945.     cancel = EVT_control_cancel(ON);
  946.  
  947.     /*  ボタンの表示  */
  948.     if ((ep = homebtn) != NULL)
  949.         EVT_set_node(ep->x1,ep->y1,ep->x2-ep->x1,ep->y2-ep->y1,
  950.                                             MEVT,MENU_clip,MEv_NULL, CLIP);
  951.     ep = NULL;
  952.     for (btn_num = i = 0; i < EXCMD_MAX; i++, btn_num++)
  953.     {
  954.         if (msg[i] == NULL)
  955.             break;
  956.         if ((ofs = (xsiz - strlen(msg[i])*8 + 1) / 2) < 0)
  957.             ofs = 0;
  958.         pbox(x,y+i*20, x+xsiz,y+i*20+19, CHR_COL,CHR_COL);
  959.         wrt(msg[i], x+ofs,y+i*20+2, BAK_COL,CHR_COL, 16);
  960.         ev[i] = EVT_set_node(x,y+i*20, xsiz,19,
  961.                                             MEVT,MENU_clip,MEv_MAX+i, PAINT);
  962.     }
  963.  
  964.     /*  イベント発生  */
  965.     MOS_disp(MOS_ON);
  966.  
  967.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  968.  
  969.     do {
  970.         menu_event = MEv_NULL;
  971.         while (menu_event == MEv_NULL && (ch = kb_check()) == 0)
  972.             EVT_loop(MEVT-1, MEVT);
  973.  
  974.         if (menu_event != MEv_NULL && pos >= 0 && ep != NULL)
  975.             DSP_clip_paint(ep), ep = NULL, pos = -1;
  976.  
  977.         if (ch)
  978.         {
  979.             switch (ch)
  980.             {
  981.               case 0x4D:        /*  ↑  */
  982.                 if (ep != NULL)
  983.                     DSP_clip_paint(ep);
  984.                 if ((--pos) < 0)
  985.                     pos = btn_num-1;
  986.                 DSP_clip_paint(ep = ev[pos]);
  987.                 break;
  988.               case 0x50:        /*  ↓  */
  989.                 if (ep != NULL)
  990.                     DSP_clip_paint(ep);
  991.                 if ((++pos) >= btn_num)
  992.                     pos = 0;
  993.                 DSP_clip_paint(ep = ev[pos]);
  994.                 break;
  995.               case 0x1D:        /*  改行、実行キーで決定  */
  996.               case 0x45:
  997.               case 0x73:
  998.                 if (pos >= 0)
  999.                     menu_event = MEv_MAX + pos;
  1000.                 else
  1001.                     menu_event = MEv_NULL;
  1002.                 break;
  1003.               case 0x01:       /*  エスケープで中止  */
  1004.                 menu_event = MEv_CANCEL;
  1005.                 break;
  1006.               default:
  1007.                 if ((p = strchr(keytbl, sc_to_char[ch])) != NULL)
  1008.                 {
  1009.                     menu_event = (p - keytbl) + MEv_MAX;
  1010.                     if (menu_event - MEv_MAX >= btn_num)
  1011.                         menu_event = MEv_NULL;
  1012.                 }
  1013.             }
  1014.             while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  1015.         }
  1016.     } while (menu_event < MEv_MAX && menu_event != MEv_CANCEL);
  1017.  
  1018.     MOS_disp(MOS_OFF);
  1019.     pbox(x,y, x+xsiz,y+btn_num*20+19, 0,0);
  1020.     MOS_disp(MOS_ON);
  1021.  
  1022.     EVT_level_free(MEVT);
  1023.     EVT_level_free(MEVT-1);
  1024.  
  1025.     EVT_control_ground(ground);
  1026.     EVT_control_cancel(cancel);
  1027.  
  1028.     if (ttlsave)
  1029.         title_backup(OFF);  /* タイトル部分の復元 */
  1030.  
  1031.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  1032.  
  1033.     return menu_event == MEv_CANCEL ? -1:(menu_event - MEv_MAX);
  1034. }
  1035.  
  1036.  
  1037. static  void    DSP_input_string(int redraw)
  1038. {
  1039. int     xpos = menu.xpos;
  1040. int     ypos = menu.ypos;
  1041. int     msgx = xpos + menu.msgx;
  1042. int     msgy = ypos + menu.msgy;
  1043. int     msgxsiz = menu.msglen*8;
  1044.  
  1045.     wind_close();
  1046.  
  1047.     DSP_select_mode(redraw);
  1048.  
  1049.     /*  スイッチ表示  */
  1050.     if (redraw)
  1051.     {
  1052.         box2(xpos+menu.sw[1].x-2,ypos+menu.sw[1].y-21,
  1053.              xpos+menu.sw[0].x+menu.swxsiz+2,ypos+menu.sw[1].y+21, B1,B2);
  1054.         wrt("英大小文字の区別",
  1055.                 xpos+menu.sw[1].x,ypos+menu.sw[1].y-19,SC,WC, 16);
  1056.     }
  1057.     DSP_switch(redraw);
  1058.  
  1059.     /*  入力行  */
  1060.     KAN_setposMode(msgx+msgxsiz+8+2-72, msgy+21);
  1061.     if (redraw)
  1062.     {
  1063.         pbox(msgx-3,msgy-2, msgx+msgxsiz+8+1,msgy+15+2, BLACK,BAK_COL);
  1064.         KAN_dispMode();     /* モード再表示 */
  1065.     }
  1066.     EVT_set_node(msgx,msgy, msgxsiz,16, MEVT,MENU_clip,MEv_CURMOVE, CLIP|CSR);
  1067. }
  1068.  
  1069. static  keytbl_t    srch_key[] = {
  1070.     { 0x24D, MEv_sDOWN}, /*  C+↑ : 逆スクロール     */
  1071.     {0xF06E, MEv_sDOWN}, /*  前行 : 逆スクロール     */
  1072.     { 0x250, MEv_sUP  }, /*  C+↓ :   スクロール     */
  1073.     {0xF070, MEv_sUP  }, /*  次行 :   スクロール     */
  1074.     {    -1, MEv_NULL }, /*  おしまい                */
  1075. };
  1076.  
  1077. mevt_t  input_string(char *buf, int only_move,
  1078.                     int *menu_x,int *menu_y, int *size_x,int *size_y,
  1079.                     int *minline, int *maxline)
  1080. {
  1081. static  int     last_x = 0, last_y = 0;
  1082. static  int     rewrite = YES;
  1083. auto    int     ch, line_num = -1;
  1084. auto    int     win_close = TRUE, move_start = TRUE;
  1085. auto    int     mos_x, mos_y;
  1086. auto    mevt_t  keyon = MEv_NULL;
  1087. const           xsiz = 352;
  1088. const           ysiz = 110;
  1089.         char    *linebuf = NULL;
  1090.  
  1091.     if (curpos < 0)
  1092.         curpos = strlen(buf);
  1093.     linebuf = buf;
  1094.  
  1095.     menu.func = DSP_input_string;
  1096.     menu.ymax = Ymax2;
  1097.  
  1098.     /*  ウィンドゥの大きさと位置  */
  1099.     *size_x = menu.xsiz = xsiz;
  1100.     *size_y = menu.ysiz = ysiz;
  1101.     if ((menu.xpos = *menu_x) < Xmin)
  1102.         menu.xpos = Xmin ;
  1103.     if (X(menu.xpos + xsiz) > X(Xmax))
  1104.         menu.xpos = X(Xmax - xsiz);
  1105.     if ((menu.ypos = *menu_y) < Ymin)
  1106.         menu.ypos = Ymin;
  1107.     if (menu.ypos + ysiz > menu.ymax)
  1108.         menu.ypos = menu.ymax - ysiz;
  1109.     menu.evt = MEv_MOVE;
  1110.  
  1111.     /*  移動のみおこなう  */
  1112.     if (only_move)
  1113.     {
  1114.         if (move_menu(last_x,last_y, menu.xpos,menu.ypos, xsiz,ysiz))
  1115.         {
  1116.             mos_rdpos(NULL, &mos_x,&mos_y);
  1117.             if (mos_x >= last_x && mos_x <= last_x+xsiz &&
  1118.                 mos_y >= last_y && mos_y <= last_y+ysiz)
  1119.             MOS_setpos(menu.xpos+mos_x-last_x, menu.ypos+mos_y-last_y);
  1120.             last_x = *menu_x = menu.xpos;
  1121.             last_y = *menu_y = menu.ypos;
  1122.         }
  1123.  
  1124.         return MEv_CANCEL;
  1125.     }
  1126.  
  1127.     /*  タイトル  */
  1128.     menu.ttl = "文字列検索";
  1129.     menu.ttllen = strlen(menu.ttl) + 4;
  1130.     menu.ttly = 6;
  1131.  
  1132.     /*  ボタン  */
  1133.     menu.btn[0].str = "↑検索", menu.btn[0].x=155;
  1134.     menu.btn[1].str = "↓検索", menu.btn[1].x=155+64;
  1135.     menu.btn[2].str = "中  止", menu.btn[2].x=155+128;
  1136.     menu.btn[0].evt = MEv_rSEARCH;
  1137.     menu.btn[1].evt = MEv_fSEARCH;
  1138.     menu.btn[2].evt = MEv_CANCEL;
  1139.     menu.btny = 80, menu.btnlen = 6, menu.btnnum = 3;
  1140.     menu.btnxsiz = 58, menu.btnysiz = 22;
  1141.  
  1142.     /*  入力行の長さ  */
  1143.     menu.msgnum = 0;
  1144.     menu.msgx = 12, menu.msgy = 36, menu.msglen = 40;
  1145.  
  1146.     /*  スイッチ  */
  1147.     menu.swnum = 2;
  1148.     menu.sw[0].str = "同一視", menu.sw[0].x = 82;
  1149.     menu.sw[1].str = "区  別", menu.sw[1].x = 11;
  1150.     menu.sw[0].evt = MEv_sSAME, menu.sw[1].evt = MEv_sDIFF;
  1151.     menu.sw[0].y = menu.sw[1].y = 83;
  1152.     menu.sw[0].sw = menu.sw[1].sw = OFF;
  1153.     menu.swxsiz = 56 ; menu.swysiz = 19;
  1154.     menu.sw[setup.caps].sw = ON;
  1155.  
  1156.     /*  画面作成  */
  1157.     MOS_disp(MOS_OFF ) ;
  1158.     DSP_input_string(rewrite);
  1159.     MOS_disp(MOS_ON);
  1160.  
  1161.     /*  ループの開始  */
  1162.     keyflush();             /* 先行入力を捨てる */
  1163.  
  1164.     *minline = *maxline = get_nowline();
  1165.                                     /* このループ内で移動した最小/最大行 */
  1166.  
  1167.     do {
  1168.         if (win_close)
  1169.         {
  1170.             wind_open(menu.xpos+menu.msgx,menu.ypos+menu.msgy,
  1171.                                         menu.msglen, &curpos, linebuf);
  1172.             win_close = FALSE;
  1173.         }
  1174.  
  1175.         for (menu_event = MEv_NULL;
  1176.              menu_event == MEv_NULL && kbhit() == FALSE;
  1177.              )
  1178.         {
  1179.             EVT_loop(MEVT_l, MEVT);
  1180.  
  1181. extern  short   auto_move;
  1182.             if (keyon != MEv_NULL &&
  1183.                 (auto_move == 0 || keyon != key_event(kb_check(), srch_key)))
  1184.             {
  1185.                 unset_auto_scroll();
  1186.                 keyon = MEv_NULL;
  1187.             }
  1188.  
  1189.             if (line_num != get_nowline())
  1190.             {
  1191.                 line_num = get_nowline();   /* 画面スクロールでの移動を確認 */
  1192.                 redisp_lnum();              /*  行番号の再表示  */
  1193.                 if (line_num < *minline) *minline = line_num;
  1194.                 if (line_num > *maxline) *maxline = line_num;
  1195.             }
  1196.         }
  1197.  
  1198.         if (kbhit())
  1199.         {
  1200.             switch (ch = getch())
  1201.             {
  1202.               case  0x101:      /*  エスケープで中止  */
  1203.                 menu_event = MEv_CANCEL; break;
  1204.  
  1205.               case  0x173:      /*  実行キーは無視 */
  1206.               case  0x145:      /*  改行キー(テンキー側)は無視 */
  1207.               case  0x11D:      /*  改行キーは無視 */
  1208.                 continue;
  1209.  
  1210.               case  0x14D:      /*  ↑  */
  1211.                 menu_event = MEv_rSEARCH; break;
  1212.               case 0x114D:      /*  SHIFT + ↑  */
  1213.                 menu_event = MEv_ErSEARCH; break;
  1214.               case 0x16E:       /*  前行  */
  1215.               case 0x214D:      /*  CTRL + ↑  */
  1216.                 set_auto_scroll(- setup.btn_speed);
  1217.                 keyon = MEv_sDOWN;
  1218.                 break;
  1219.  
  1220.               case  0x150:      /*  ↓  */
  1221.                 menu_event = MEv_fSEARCH; break;
  1222.               case 0x1150:      /*  SHIFT + ↓  */
  1223.                 menu_event = MEv_FfSEARCH; break;
  1224.               case 0x170:       /*  次行  */
  1225.               case 0x2150:      /*  CTRL + ↓  */
  1226.                 set_auto_scroll(setup.btn_speed);
  1227.                 keyon = MEv_sUP;
  1228.                 break;
  1229.  
  1230.               case 0x214F:      /*  CTRL + ← [区別]  */
  1231.                 menu_event = MEv_sDIFF; break;
  1232.               case 0x2151:      /*  CTRL + → [同一視]  */
  1233.                 menu_event = MEv_sSAME; break;
  1234.  
  1235.               default:
  1236.                 inpch(ch);          break;
  1237.             }
  1238.         }
  1239.  
  1240.         switch (menu_event)
  1241.         {
  1242.           case MEv_MOVE:  /*  ウィンドゥ移動開始/終了  */
  1243.             if (move_start)
  1244.             {
  1245.                 wind_close() ;
  1246.                 MOS_disp(MOS_OFF);
  1247.                 move_start = FALSE ;
  1248.                 break ;
  1249.             }
  1250.             else
  1251.                 move_start = TRUE ;
  1252.           case MEv_CURMOVE:  /*  カーソル移動  */
  1253.             win_close = TRUE ;
  1254.             break ;
  1255.  
  1256.           case MEv_sSAME:  /*  同一視  */
  1257.           case MEv_sDIFF:  /*  区別  */
  1258.             if (setup.caps != menu_event - MEv_sSAME)
  1259.                 setup.caps = DSP_rev(setup.caps, menu_event - MEv_sSAME);
  1260.             break ;
  1261.         }
  1262.     } while (menu_event != MEv_CANCEL &&
  1263.                 menu_event != MEv_rSEARCH  && menu_event != MEv_fSEARCH &&
  1264.                 menu_event != MEv_ErSEARCH && menu_event != MEv_FfSEARCH);
  1265.  
  1266.     wind_close() ;
  1267.  
  1268.     MOS_disp( MOS_OFF ) ;
  1269.  
  1270.     EVT_level_free( MEVT ) ;
  1271.  
  1272.     if (menu_event == MEv_CANCEL)   /*  中止  */
  1273.     {
  1274.         pbox( menu.xpos,menu.ypos,
  1275.                 menu.xpos+menu.xsiz,menu.ypos+menu.ysiz, 0,0 ) ;
  1276.         rewrite = YES ;
  1277.     }
  1278.     else
  1279.         rewrite = NO ;
  1280.  
  1281.     MOS_disp( MOS_ON ) ;
  1282.  
  1283.     last_x = *menu_x = menu.xpos ;
  1284.     last_y = *menu_y = menu.ypos ;
  1285.  
  1286.     while (kb_check() != 0) ;   /* キーから手を離すまで待つ */
  1287.  
  1288.     return menu_event;
  1289. }
  1290.  
  1291. void    report_fatal_error( err_t type, char *err_msg )
  1292. {
  1293. static  int     xc = MENU_CENTERING, yc = MENU_CENTERING;
  1294.     int     mos;
  1295.     char    tmp[80];
  1296.  
  1297.     mos = get_mos_ptn() ;
  1298.  
  1299.     DSP_writePage( gwork, 1 ) ;
  1300.  
  1301.     switch( type )
  1302.     {
  1303.       case ERR_FILE: msg[0] = "ファイル読み込み時に問題が発生" ; break ;
  1304.       case ERR_EXEC: msg[0] = "外部コマンド起動時に問題が発生" ; break ;
  1305.     }
  1306.     msg[1] = msg[2] = NULL ;
  1307.  
  1308.     if( err_msg != NULL )
  1309.     {
  1310.         /* sprintf( tmp, "(%s)", err_msg ), msg[1] = tmp ; */
  1311.         *tmp = '\0' ;
  1312.         _strcats( 80, tmp, "(", err_msg, ")", NULL ) ;
  1313.         msg[1] = tmp ;
  1314.     }
  1315.     btn[0] = "確  認" ;
  1316.     btn[1] = NULL ;
  1317.     select_mode("! WARNING !", msg, btn, 20, &xc,&yc);
  1318.  
  1319.     set_mos_ptn( mos ) ;
  1320. }
  1321.  
  1322.